package com.peter.electronicmall.base

import android.content.Context
import android.content.IntentFilter
import android.graphics.PixelFormat
import android.graphics.Rect
import android.os.Bundle
import android.os.IBinder
import android.support.annotation.LayoutRes
import android.support.v7.app.AppCompatActivity
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import com.peter.baselibrary.R
import com.peter.baselibrary.events.NetworkChangeEvent
import com.peter.baselibrary.receiver.NetworkConnectChangedReceiver
import com.peter.baselibrary.utils.NetUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode


/**
 * Created by peter on 2018/5/17.
 */

abstract class BaseActivity : AppCompatActivity() {

    private var mCheckNetWork = true //默认检查网络状态
    private var mTipView: View? = null
    private var mWindowManager: WindowManager? = null
    private var mReceiver: NetworkConnectChangedReceiver? = null
    private var mLayoutParams: WindowManager.LayoutParams? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        requestWindowFeature(Window.FEATURE_NO_TITLE)
        setContentView(getLayoutId())
        Companion.contentView = window.decorView.findViewById(android.R.id.content)
        createReceiver()
        initTipView() //初始化提示View
        EventBus.getDefault().register(this)
        initData()
        initView()
    }

    /**
     * 动态注册接收网络状态改变的广播
     */
    private fun createReceiver() {
        val filter = IntentFilter()
        filter.addAction("android.NET.conn.CONNECTIVITY_CHANGE")
        filter.addAction("android.Net.wifi.WIFI_STATE_CHANGED")
        filter.addAction("android.net.wifi.STATE_CHANGE")
        mReceiver = NetworkConnectChangedReceiver()
        this.registerReceiver(mReceiver, filter)
    }

    @LayoutRes
    abstract fun getLayoutId(): Int

    abstract fun initView()

    abstract fun initData()

    override fun onResume() {
        super.onResume()
        //在无网络情况下打开APP时，系统不会发送网络状况变更的Intent，需要自己手动检查
        hasNetWork(NetUtils.isConnected(applicationContext))
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(mReceiver)
        EventBus.getDefault().unregister(this)
    }

    override fun finish() {
        super.finish()
        //当提示View被动态添加后直接关闭页面会导致该View内存溢出，所以需要在finish时移除
        if (mTipView != null && mTipView?.parent != null) {
            mWindowManager?.removeView(mTipView)
        }
    }

    /**
     * 打卡软键盘
     */
    fun openKeyBord(mEditText: EditText, mContext: Context) {
        val imm = mContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN)
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
    }

    /**
     * 关闭软键盘
     */
    fun closeKeyBord(mEditText: EditText, mContext: Context) {
        val imm = mContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(mEditText.windowToken, 0)
    }

    /**
     * 多种隐藏软件盘方法的其中一种
     *
     * @param token
     */
    private fun hideSoftInput(token: IBinder?) {
        if (token != null) {
            val im = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            im.hideSoftInputFromWindow(token,
                    InputMethodManager.HIDE_NOT_ALWAYS)
        }
    }


    override fun dispatchTouchEvent(event: MotionEvent): Boolean {
        if (event.action == MotionEvent.ACTION_DOWN) {
            val v = currentFocus
            //如果点击除EditText以外的其他VIew，键盘回收
            if (v is EditText) {
                val nextFocus = findViewFocus(window.decorView.findViewById(android.R.id.content), event)
                if (nextFocus != null && nextFocus is EditText) {
                    return super.dispatchTouchEvent(event)
                }
                val outRect = Rect()
                v.getGlobalVisibleRect(outRect)
                if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
                    hideSoftInput(v.windowToken)
                    Companion.contentView?.requestFocus()
                    v.clearFocus()
                }
            }
        }
        return super.dispatchTouchEvent(event)
    }

    private fun findViewFocus(viewGroup: ViewGroup, event: MotionEvent): View? {
        var view: View? = null
        val childCount = viewGroup.childCount
        for (i in 0 until childCount) {
            view = viewGroup.getChildAt(i)
            val outRect = Rect()
            view!!.getGlobalVisibleRect(outRect)
            if (outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
                return if (view is ViewGroup) {
                    findViewFocus((view as ViewGroup?)!!, event)
                } else {
                    view
                }
            }
        }
        return null
    }

    companion object {
        private var contentView: View? = null
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onNetworkChangeEvent(event: NetworkChangeEvent) {
        hasNetWork(event.isConnected)
    }

    private fun hasNetWork(has: Boolean) {
        if (isCheckNetWork()) {
            if (has) {
                if (mTipView != null && mTipView?.parent != null) {
                    mWindowManager?.removeView(mTipView)
                }
                onReConnect()
            } else {
                if (mTipView?.parent == null) {
                    mWindowManager?.addView(mTipView, mLayoutParams)
                }
            }
        }
    }

    abstract fun onReConnect()

    fun setCheckNetWork(checkNetWork: Boolean) {
        mCheckNetWork = checkNetWork
    }

    fun isCheckNetWork(): Boolean {
        return mCheckNetWork
    }

    private fun initTipView() {
        val inflater = layoutInflater
        mTipView = inflater.inflate(R.layout.layout_network_tip, null) //提示View布局
        mWindowManager = this.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        mLayoutParams = WindowManager.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_APPLICATION,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                PixelFormat.TRANSLUCENT)
        //使用非CENTER时，可以通过设置XY的值来改变View的位置
        mLayoutParams?.gravity = Gravity.TOP
        mLayoutParams?.x = 0
        mLayoutParams?.y = 0
    }
}
